#include <stdio.h>
#include <string.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

#define NUM 10

typedef void(*func_t)();//函数指针重命名位func_t

func_t handlerTask[NUM];

//样例任务
void task1()
{
    printf("handler task1\n");
}

void task2()
{
    printf("handler task2\n");
}

void task3()
{
    printf("handler task3\n");
}

void loadTask()
{
    memset(handlerTask,0,sizeof(handlerTask));
    handlerTask[0] = task1;
    handlerTask[1] = task2;
    handlerTask[2] = task3;
}


int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        //子进程
        int cnt = 5;
        while(cnt)
        {
            printf("我是子进程:%d,父进程:%d,cnt:%d\n",getpid(),getppid(),cnt--);
            sleep(3);
        }
        //退出子进程
        exit(10);
    }
    //父进程,子进程到此处前就已经exit退出了
    //轮询非阻塞式等待 
    loadTask();//装载任务
    int status = 0;
    while(1)
    {
        pid_t ret = waitpid(id,&status,WNOHANG);//WONHANG:非阻塞->子进程没有退出，父进程检查后，立即返回
        if(ret == 0)
        {
            //waitpid调用成功&&子进程没有退出
            //子进程没有退出，我的waitpid没有等待失败，仅仅是检测到了子进程没有退出
            //TODO
            printf("wait done,but child is running...\n");
            for(int i = 0; handlerTask[i] != NULL;i++)
            {
                handlerTask[i]();//通过函数回调的方式，执行我们想让父进程在
            }
        }
        else if(ret > 0)
        {
            //waitpid调用成功&&子进程退出了
            printf("wait success,exit_code:%d, sig:%d\n",(status>>8) & 0xFF , status & 0x7F);
            break;
        }
        else 
        {    
            //waitpid调用失败
            printf("waitpid call pailed\n");
            break;
        }
        sleep(1);
    }


    return 0;
}
